package com.net.entity;

import com.tank.control.DirectionEnum;
import com.tank.entrity.Bullet;
import com.tank.entrity.GroupType;
import com.tank.entrity.Tank;
import com.tank.model.GameModel;
import lombok.*;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.util.UUID;

@Slf4j
@Data
@ToString
@EqualsAndHashCode(callSuper = true)
public class BulletNewMessage extends Message {
    private UUID playerID;
    private UUID id;
    int x, y;
    private DirectionEnum dir;
    private GroupType group;

    public BulletNewMessage(Bullet bullet) {
        this.playerID = bullet.getPlayerId();
        this.id = bullet.getId();
        this.x = (int) bullet.getX();
        this.y = (int) bullet.getY();
        this.dir = bullet.getDirectionEnum();
        this.group = bullet.getGroupType();
    }
    public BulletNewMessage() {}
    @Override
    public void handle() {
        if (this.playerID.equals(((Tank)GameModel.INSTANCE.getMainTank()).getUuid())) {
            return;
        }

        Bullet bullet = new Bullet(this.playerID, x + (GameModel.INSTANCE.getMainTank().getWidth() / 2), y, dir, group);
        bullet.setId(this.id);
        GameModel.INSTANCE.addObject(bullet);
    }

    @Override
    @SneakyThrows
    public byte[] toBytes() {
        @Cleanup ByteArrayOutputStream baos = new ByteArrayOutputStream();
        @Cleanup DataOutputStream dos = new DataOutputStream(baos);
        dos.writeLong(this.playerID.getMostSignificantBits());
        dos.writeLong(this.playerID.getLeastSignificantBits());
        dos.writeLong(id.getMostSignificantBits());
        dos.writeLong(id.getLeastSignificantBits());
        dos.writeInt(x);
        dos.writeInt(y);
        dos.writeInt(dir.ordinal());
        dos.writeInt(group.ordinal());
        dos.flush();
        return baos.toByteArray();
    }

    @Override
    @SneakyThrows
    public void parse(byte[] bytes) {
        @Cleanup DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes));
        this.playerID = new UUID(dis.readLong(), dis.readLong());
        this.id = new UUID(dis.readLong(), dis.readLong());
        this.x = dis.readInt();
        this.y = dis.readInt();
        this.dir = DirectionEnum.values()[dis.readInt()];
        this.group = GroupType.values()[dis.readInt()];
    }

    @Override
    public MessageType getMessageType() {
        return MessageType.BulletNew;
    }
}
